﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Runtime.Serialization;
using Roberts.MvcExtensions;

namespace Roberts.MvcExtensions.Tests
{
    [TestClass]
    public class SerializationTests
    {
        [TestMethod]
        public void ToJsonWithJavascriptSerializerNamesCorrectly()
        {
            var testModel = new TestJsonClass() { PropA = "hello", PropB = 2, NullPropC = null, NotDataMember="world" };
            var result = testModel.ToJSON(false);
            string expected = "{\"PropA\":\"hello\",\"PropB\":2,\"NullPropC\":null,\"NotDataMember\":\"world\"}";
            Assert.AreEqual(result, expected);
        }

        [TestMethod]
        public void ToJsonWithJavascriptSerializerAndNullValue()
        {
            TestJsonClass testModel = null;
            var result = testModel.ToJSON(false);
            string expected = "null";
            Assert.AreEqual(result, expected);
        }

        [TestMethod]
        public void ToJsonWithDataContractSerializerNamesCorrectly()
        {
            var testModel = new TestJsonClass() { PropA = "hello", PropB = 2, NullPropC = null, NotDataMember = "world" };
            var result = testModel.ToJSON(true);
            string expected = "{\"prop-a\":\"hello\",\"prop-b\":2,\"null-prop-c\":null}";
            Assert.AreEqual(result, expected);
        }

        [TestMethod]
        public void ToJsonWithDataContractSerializerAndNullValue()
        {
            TestJsonClass testModel = null;
            var result = testModel.ToJSON(true);
            string expected = "null";
            Assert.AreEqual(result, expected);
        }

        [TestMethod]
        public void ToJsonWithJavascriptSerializerAndNestedTypes()
        {
            Guid id = new Guid("AD1C1240-BC2D-4856-A4CB-1B9DC553525D");

            var class1 =  new TestJsonClass() { PropA = "hello", PropB = 2, NullPropC = null, NotDataMember="world" };
            var class2 =  new TestJsonClass() { PropA = "hell2", PropB = 3, NullPropC = 1, NotDataMember="world2" };
            var testModel = new TestNestedClass() { Details = new List<TestJsonClass> { class1, class2 }, Id = id };

            var result =testModel.ToJSON(false);
            string expected = "{\"Details\":[{\"PropA\":\"hello\",\"PropB\":2,\"NullPropC\":null,\"NotDataMember\":\"world\"},{\"PropA\":\"hell2\",\"PropB\":3,\"NullPropC\":1,\"NotDataMember\":\"world2\"}],\"Id\":\"ad1c1240-bc2d-4856-a4cb-1b9dc553525d\"}";
            Assert.AreEqual(result, expected);
        }

        [TestMethod]
        public void ToJsonWithDatacontractSerializerAndNestedTypes()
        {
            Guid id = new Guid("AD1C1240-BC2D-4856-A4CB-1B9DC553525D");

            var class1 = new TestJsonClass() { PropA = "hello", PropB = 2, NullPropC = null, NotDataMember = "world" };
            var class2 = new TestJsonClass() { PropA = "hell2", PropB = 3, NullPropC = 1, NotDataMember = "world2" };
            var testModel = new TestNestedClass() { Details = new List<TestJsonClass> { class1, class2 }, Id = id };

            var result = testModel.ToJSON(true);
            string expected = "{\"details-list\":[{\"prop-a\":\"hello\",\"prop-b\":2,\"null-prop-c\":null},{\"prop-a\":\"hell2\",\"prop-b\":3,\"null-prop-c\":1}],\"id\":\"ad1c1240-bc2d-4856-a4cb-1b9dc553525d\"}";
            Assert.AreEqual(result, expected);
        }

        [DataContract]
        public class TestNestedClass
        {
            [DataMember(Name = "details-list")]
            public List<TestJsonClass> Details { get; set; }

            [DataMember(Name="id")]
            public Guid Id { get; set; }
        }

        [DataContract]
        public class TestJsonClass
        {
            [DataMember(Name = "prop-a", Order=1)]
            public string PropA { get; set; }

            [DataMember(Name = "prop-b", Order=2)]
            public int PropB { get; set; }

            [DataMember(Name="null-prop-c", Order=3)]
            public int? NullPropC { get; set; }

            public string NotDataMember { get; set; }
        }
    }
}
